using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace Albatross.WCF.Extenions.ServiceModel.Channels
{
    internal class CompressionInputChannel<TChannelShape> : CompressionChannel<TChannelShape>, IInputChannel
        where TChannelShape : class, IInputChannel
    {
        internal CompressionInputChannel(ChannelManagerBase channelManagerBase, TChannelShape innerChannel)
            : base(channelManagerBase, innerChannel)
        {
        }

        #region IInputChannel Members

        public IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state)
        {
            return InnerChannel.BeginReceive(timeout, callback, state);
        }

        public IAsyncResult BeginReceive(AsyncCallback callback, object state)
        {
            return InnerChannel.BeginReceive(callback, state);
        }

        public IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)
        {
            return InnerChannel.BeginTryReceive(timeout, callback, state);
        }

        public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state)
        {
            return InnerChannel.BeginWaitForMessage(timeout, callback, state);
        }

        public Message EndReceive(IAsyncResult result)
        {
            return InnerChannel.EndReceive(result);
        }

        public bool EndTryReceive(IAsyncResult result, out Message message)
        {
            bool innerResult = InnerChannel.EndTryReceive(result, out message);

            if (innerResult && message != null)
            {
                message = MessageCompressor.DecompressMessage(message);
            }

            return innerResult;
        }

        public bool EndWaitForMessage(IAsyncResult result)
        {
            return InnerChannel.EndWaitForMessage(result);
        }

        public EndpointAddress LocalAddress
        {
            get { return InnerChannel.LocalAddress; }
        }

        public Message Receive(TimeSpan timeout)
        {
            Message msg = InnerChannel.Receive(timeout);
            if (msg != null)
            {
                return MessageCompressor.DecompressMessage(msg);
            }
            return msg;
        }

        public Message Receive()
        {
            Message msg = InnerChannel.Receive();
            if (msg != null)
            {
                return MessageCompressor.DecompressMessage(msg);
            }
            return msg;
        }

        public bool TryReceive(TimeSpan timeout, out Message message)
        {
            bool innerResult = InnerChannel.TryReceive(timeout, out message);
            if (innerResult && message != null)
            {
                message = MessageCompressor.DecompressMessage(message);
            }
            return innerResult;
        }

        public bool WaitForMessage(TimeSpan timeout)
        {
            return InnerChannel.WaitForMessage(timeout);
        }

        #endregion
    }
}